{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "32f568fc",
   "metadata": {},
   "source": [
    "一个简单的示例，其中两个 agent 从 10 倒数到 1。\n",
    "\n",
    "我们首先定义 agent 类及其各自的处理消息的程序。 \n",
    "\n",
    "我们创建两个 agent 类：Modifier 和 Checker。\n",
    "\n",
    "Modifier agent 修改给定的数字，而 Check agent 根据条件检查该值。 \n",
    "\n",
    "我们还创建了一个 Message 数据类，它定义了在 agent 之间传递的消息。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c3c5c6d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "from dataclasses import dataclass\n",
    "from typing import Callable\n",
    "\n",
    "from autogen_core import DefaultTopicId, MessageContext, RoutedAgent, default_subscription, message_handler\n",
    "\n",
    "\n",
    "@dataclass\n",
    "class Message:\n",
    "    content: int\n",
    "\n",
    "\n",
    "@default_subscription\n",
    "class Modifier(RoutedAgent):\n",
    "    def __init__(self, modify_val: Callable[[int], int]) -> None:\n",
    "        super().__init__(\"A modifier agent.\")\n",
    "        self._modify_val = modify_val\n",
    "\n",
    "    @message_handler\n",
    "    async def handle_message(self, message: Message, ctx: MessageContext) -> None:\n",
    "        val = self._modify_val(message.content)\n",
    "        print(f\"{'-'*80}\\nModifier:\\nModified {message.content} to {val}\")\n",
    "        await self.publish_message(Message(content=val), DefaultTopicId())  # type: ignore\n",
    "\n",
    "\n",
    "@default_subscription\n",
    "class Checker(RoutedAgent):\n",
    "    def __init__(self, run_until: Callable[[int], bool]) -> None:\n",
    "        super().__init__(\"A checker agent.\")\n",
    "        self._run_until = run_until\n",
    "\n",
    "    @message_handler\n",
    "    async def handle_message(self, message: Message, ctx: MessageContext) -> None:\n",
    "        if not self._run_until(message.content):\n",
    "            print(f\"{'-'*80}\\nChecker:\\n{message.content} passed the check, continue.\")\n",
    "            await self.publish_message(Message(content=message.content), DefaultTopicId())\n",
    "        else:\n",
    "            print(f\"{'-'*80}\\nChecker:\\n{message.content} failed the check, stopping.\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec134bce",
   "metadata": {},
   "source": [
    "您可能已经注意到，agent 的逻辑（无论是使用模型还是代码执行器）与消息的传递方式完全分离。 \n",
    "\n",
    "这是核心思想：框架提供通信基础设施，agent 负责自己的逻辑。 我们将通信基础设施称为 **Agent 运行时**。\n",
    "\n",
    "Agent 运行时是此框架的关键概念。 除了传递消息之外，它还管理 agent 的生命周期。 因此，agent 的创建由运行时处理。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "f40779ac",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--------------------------------------------------------------------------------\n",
      "Checker:\n",
      "10 passed the check, continue.\n",
      "--------------------------------------------------------------------------------\n",
      "Modifier:\n",
      "Modified 10 to 9\n",
      "--------------------------------------------------------------------------------\n",
      "Checker:\n",
      "9 passed the check, continue.\n",
      "--------------------------------------------------------------------------------\n",
      "Modifier:\n",
      "Modified 9 to 8\n",
      "--------------------------------------------------------------------------------\n",
      "Checker:\n",
      "8 passed the check, continue.\n",
      "--------------------------------------------------------------------------------\n",
      "Modifier:\n",
      "Modified 8 to 7\n",
      "--------------------------------------------------------------------------------\n",
      "Checker:\n",
      "7 passed the check, continue.\n",
      "--------------------------------------------------------------------------------\n",
      "Modifier:\n",
      "Modified 7 to 6\n",
      "--------------------------------------------------------------------------------\n",
      "Checker:\n",
      "6 passed the check, continue.\n",
      "--------------------------------------------------------------------------------\n",
      "Modifier:\n",
      "Modified 6 to 5\n",
      "--------------------------------------------------------------------------------\n",
      "Checker:\n",
      "5 passed the check, continue.\n",
      "--------------------------------------------------------------------------------\n",
      "Modifier:\n",
      "Modified 5 to 4\n",
      "--------------------------------------------------------------------------------\n",
      "Checker:\n",
      "4 passed the check, continue.\n",
      "--------------------------------------------------------------------------------\n",
      "Modifier:\n",
      "Modified 4 to 3\n",
      "--------------------------------------------------------------------------------\n",
      "Checker:\n",
      "3 passed the check, continue.\n",
      "--------------------------------------------------------------------------------\n",
      "Modifier:\n",
      "Modified 3 to 2\n",
      "--------------------------------------------------------------------------------\n",
      "Checker:\n",
      "2 passed the check, continue.\n",
      "--------------------------------------------------------------------------------\n",
      "Modifier:\n",
      "Modified 2 to 1\n",
      "--------------------------------------------------------------------------------\n",
      "Checker:\n",
      "1 failed the check, stopping.\n"
     ]
    }
   ],
   "source": [
    "from autogen_core import AgentId, SingleThreadedAgentRuntime\n",
    "\n",
    "# Create a local embedded runtime.\n",
    "runtime = SingleThreadedAgentRuntime()\n",
    "\n",
    "# Register the modifier and checker agents by providing\n",
    "# their agent types, the factory functions for creating instance and subscriptions.\n",
    "await Modifier.register(\n",
    "    runtime,\n",
    "    \"modifier\",\n",
    "    # Modify the value by subtracting 1\n",
    "    lambda: Modifier(modify_val=lambda x: x - 1),\n",
    ")\n",
    "\n",
    "await Checker.register(\n",
    "    runtime,\n",
    "    \"checker\",\n",
    "    # Run until the value is less than or equal to 1\n",
    "    lambda: Checker(run_until=lambda x: x <= 1),\n",
    ")\n",
    "\n",
    "# Start the runtime and send a direct message to the checker.\n",
    "runtime.start()\n",
    "await runtime.send_message(Message(10), AgentId(\"checker\", \"default\"))\n",
    "await runtime.stop_when_idle()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "617130a9",
   "metadata": {},
   "source": [
    "从 agent 的输出中，我们可以看到该值已成功从 10 递减到 1，正如 modifier 和 checker 条件所规定。\n",
    "\n",
    "AutoGen 还支持分布式 agent 运行时，它可以托管在不同进程或机器上运行的具有不同身份、语言和依赖项的 agent。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6fb5716e",
   "metadata": {},
   "source": [
    "https://msdocs.cn/autogen/stable/user-guide/core-user-guide/design-patterns/intro.html\n",
    "\n",
    "autogen 多代理模式的几个典型应用场景： 工作流、群聊、辩论、反思"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
